﻿using MailKit;
using MailKit.Net.Pop3;
using MimeKit;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace EmailHelper.POP3
{
    /// <summary>
    /// pop3帮助类
    /// </summary>
    public class Pop3Helper
    {
        private static CancellationToken GetCancelToken(CancellationToken cancellationToken)
        {
            if (cancellationToken == default)
            {
                CancellationTokenSource tokenSource = new CancellationTokenSource();
                tokenSource.CancelAfter(10000);
                cancellationToken = tokenSource.Token;
            }
            return cancellationToken;
        }

        /// <summary>
        /// 异步获取指定index的消息UID
        /// </summary>
        /// <param name="client"></param>
        /// <param name="index"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<string> GetMessageUid(Pop3Client client, int index, CancellationToken cancellationToken = default)
        {
            if (!client.SupportsUids)
                throw new Exception("The POP3 server does not support UIDs!");
            return client.GetMessageUidAsync(index, cancellationToken);
        }

        /// <summary>
        /// 异步获取可用消息UID的完整列表
        /// </summary>
        /// <param name="client"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<IList<string>> GetMessageUids(Pop3Client client, CancellationToken cancellationToken = default)
        {
            if (!client.SupportsUids)
                throw new Exception("The POP3 server does not support UIDs!");
            return client.GetMessageUidsAsync(cancellationToken);
        }

        /// <summary>
        /// 异步获取指定索引处的消息。
        /// </summary>
        /// <param name="client"></param>
        /// <param name="index"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<MimeMessage> GetMessage(Pop3Client client, int index, ITransferProgress progress = null, CancellationToken cancellationToken = default)
        {
            return client.GetMessageAsync(index, cancellationToken, progress);
        }

        /// <summary>
        /// 异步获取指定索引处的消息。批量
        /// </summary>
        /// <param name="client"></param>
        /// <param name="indexs"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<IList<MimeMessage>> GetMessages(Pop3Client client, List<int> indexs, CancellationToken cancellationToken = default)
        {
            if (!client.Capabilities.HasFlag(Pop3Capabilities.Pipelining))
                throw new Exception("The POP3 server does not support Pipelining!");
            return client.GetMessagesAsync(indexs, cancellationToken);
        }

        /// <summary>
        /// 异步获取指定消息的大小（以字节为单位）。
        /// </summary>
        /// <param name="client"></param>
        /// <param name="index"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<int> GetMessageSize(Pop3Client client, int index, CancellationToken cancellationToken = default)
        {
            return client.GetMessageSizeAsync(index, cancellationToken);
        }

        /// <summary>
        /// 异步获取指定索引处的邮件头。
        /// </summary>
        /// <param name="client"></param>
        /// <param name="index"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<HeaderList> GetMessageHeaders(Pop3Client client, int index, CancellationToken cancellationToken = default)
        {
            cancellationToken = GetCancelToken(cancellationToken);
            return client.GetMessageHeadersAsync(index, cancellationToken);
        }

        /// <summary>
        /// 异步获取指定索引处的邮件头。批量
        /// </summary>
        /// <param name="client"></param>
        /// <param name="indexs"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task<IList<HeaderList>> GetMessageHeaders(Pop3Client client, IList<int> indexs, CancellationToken cancellationToken = default)
        {
            if (!client.Capabilities.HasFlag(Pop3Capabilities.Pipelining))
                throw new Exception("The POP3 server does not support Pipelining!");
            return client.GetMessageHeadersAsync(indexs, cancellationToken);
        }

        /// <summary>
        /// 异步将指定的消息标记为删除。
        /// </summary>
        /// <param name="client"></param>
        /// <param name="indexs"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task DeleteMessages(Pop3Client client, List<int> indexs, CancellationToken cancellationToken = default)
        {
            return client.DeleteMessagesAsync(indexs, cancellationToken);
        }

        /// <summary>
        /// 异步断开服务。如果quit为true，将发出QUIT命令以完全断开连接。
        /// </summary>
        /// <param name="client"></param>
        /// <param name="quit"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task Disconnect(Pop3Client client, bool quit, CancellationToken cancellationToken = default)
        {
            if (client.IsConnected)
            {
                return client.DisconnectAsync(quit, cancellationToken);
            }
            return Task.Delay(10);
        }
    }
}
